# coding= utf-8

import sys
import codecs
import warnings
import pymongo
from typing import List

sys.stdout = codecs.getwriter('utf-8')(sys.stdout.detach())
warnings.filterwarnings("ignore")


class Category:
    def __init__(self):
        self.config = []

        # 连接MongoDB
        self.myclient = pymongo.MongoClient("mongodb://localhost:27017/")
        mydb = self.myclient["xp_analyse"]
        self.my_category = mydb["wt_category"]
        self.my_product = mydb["wt_order_product"]
        self.my_config = mydb["wt_config"]
        self.my_task = mydb["wt_task"]

    def update_category(self, config):
        self.config = config
        all_category = self.my_category.find({'month': self.config['month'], 'domainId': translate_locale(self.config['country']), "updated": {"$exists": False}})

        for i in all_category:
            # 获取该分类下所有子分类
            ids = self.get_all_children(int(i['catId']))
            match = {'month': self.config['month'], 'domain_id': i['domainId'], 'category_id': {"$in": ids}}
            # 更新该分类的订单量等数据
            pipeline = [
                {'$match': match},
                {
                    '$group': {
                        '_id': None,
                        'order_num_total': {
                            '$sum': {'$toInt': '$order_num'},
                        },
                        'order_count_total': {
                            '$sum': {'$toInt': '$order_counts'},
                        },
                        'sku_count_total': {
                            '$sum': {'$toInt': '$sku_count'},
                        },
                        'sj_name_arr': {
                            '$addToSet': "$sj_name"
                        }
                    },
                }
            ]

            # # 获取订单量等数据并更新分类表
            result = list(self.my_product.aggregate(pipeline))
            if len(result) > 0:
                item = result[0]
                sj_name_total = len(item['sj_name_arr'])
                print(sj_name_total)
                re = self.my_category.update_one({"catId": i['catId'], 'month': self.config['month']}, {"$set": {"order_num_total": item['order_num_total'], "order_count_total": item['order_count_total'], "sku_count_total": item['sku_count_total'], "sj_name_total": sj_name_total}})
                print('分类' + i['name'] + '需更新订单量数据，更新' + str(re.modified_count) + '条')
            else:
                print('分类无订单量等数据！')

            # 反向更新自身标记已更新分类中订单量等数据
            update_re = self.my_category.update_one({"catId": i['catId'], 'month': self.config['month']}, {"$set": {"updated": True}})
            print('分类' + i['name'] + '已更新，' + str(update_re.modified_count))

    def get_all_children(self, cat_id: int) -> List[int]:
        ids = []
        self.get_all_subcategories_ids(cat_id, ids)
        return ids

    def get_all_subcategories_ids(self, cat_id: int, ids: List[int]):
        # 将当前分类ID存入结果列表中
        ids.append(cat_id)

        # 查询当前分类
        category = self.my_category.find_one({"catId": cat_id, 'month': self.config['month']})
        if category and category['children_num'] > 0:
            cat_arr = category['children_str'].split(',')
            for value in cat_arr:
                # 递归调用，获取每个子分类的所有下级分类ID，并将其存入结果列表中
                self.get_all_subcategories_ids(int(value), ids)

    def run_all_country(self):
        month = sys.argv[1]

        # 更新分类树订单量状态进行中
        self.my_task.update_one({"month": month}, {"$set": {"update_category_completed": 'pending'}})
        for i in ['it', 'de', 'us', 'uk', 'fr', 'jp', 'ca', 'es']:
            config = {'country': i, 'month': month}
            self.update_category(config)
            print('国家' + i + '更新完毕！')

        # 更新分类树订单量状态已完成
        self.my_task.update_one({"month": month}, {"$set": {"update_category_completed": 'completed'}})
        print('更新完毕')
        self.myclient.close()


def translate_locale(domain):
    dis = {'us': 1, 'uk': 2, 'de': 3, 'fr': 4, 'jp': 5, 'ca': 6, 'it': 8, 'es': 9, 'in': 10, 'mx': 11}
    return dis.get(domain)


category = Category()
category.run_all_country()
